//////////////////////////////////////////////////////////////////////////

#ifndef _OBSERVER_H_
#define _OBSERVER_H_

//////////////////////////////////////////////////////////////////////////

#include <set>

//////////////////////////////////////////////////////////////////////////

class Observable;

//////////////////////////////////////////////////////////////////////////


/** This class implements Observer design pattern
*
*   Usage: 
*   1. Create a subclass of Observer and implement OnEvent() method;
*   2. Add desired events to observe;
*   3. Pass a pointer (this) to AddObserver method() in the Observable
*      object to make the observer work;
*   4. Pass a pointer (this) to RemoveObserver method() in the Observable
*      object to stop observing.
*
*  @author   Roman Pasechnik
*  @since    Aug 04th, 2009
*  @updated  Aug 04th, 2009
*/
class Observer
{
//////////////////////////////////////////////////////////////////////////

public:

//////////////////////////////////////////////////////////////////////////


    /** Destructor */
    virtual ~Observer();


//////////////////////////////////////////////////////////////////////////


    /** Events, that can be handled by observer */
    enum Event
    {
        NETWORK_RECEIVE_COMPLETE,
        NETWORK_SEND_COMPLETE,
        NETWORK_ACCEPTED_NEW_CONNECTION
    };


    /** Add an event to observe */
    void AddEventToObserve( Event _event );


    /** Checks, if object observes this event */
    bool IsEventToObserve( Event _event ) const;


//////////////////////////////////////////////////////////////////////////


    /** Notify observer about event */
    virtual void OnEvent( Event _event, Observable* _observable ) = 0;


//////////////////////////////////////////////////////////////////////////

private:

//////////////////////////////////////////////////////////////////////////


    /** [Utility type]: a set of events */
    typedef std::set<Event> Events;


    /** All events to observe */
    Events m_EventsToObserve;


//////////////////////////////////////////////////////////////////////////
};


//////////////////////////////////////////////////////////////////////////

#endif

//////////////////////////////////////////////////////////////////////////

